﻿using System;
using System.Collections.Generic;
using System.Text;
using JWFW.SFL;
using JWFW.Model.Register.BRL;
using JWFW.Encrypt;

namespace JWFW.Model.Register
{
    /// <summary>
    /// 服务端使用的注册类
    /// </summary>
    public class RegServer
    {
#if Server
        public RegServer()
        {
        }
        /// <summary>
        /// 将注册信息中的一项转换为注册码需要的构造
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        protected string ConvertItem(string item)
        {

            return "";
        }

        /// <summary>
        /// 获取注册码
        /// </summary>
        /// <param name="name"></param>
        /// <param name="toolCode"></param>
        /// <param name="date"></param>
        /// <param name="number"></param>
        /// <param name="reflectorInfo"></param>
        /// <returns></returns>
        public static string GetRegisterCode(string name, string toolCode, DateTime date, int number, string reflectorInfo)
        {
            string tmpName = CommonOP.EncryptString(name);
            string tmpToolCode = CommonOP.EncryptString(toolCode);
            string tmpDate = CommonOP.EncryptString(date.ToString("yyyy-MM-dd"));
            string tmpNum = CommonOP.EncryptString(Guid.NewGuid().ToString().Substring(0, 4).Insert(2, number.ToString()));
            string tmpReflectorInfo = CommonOP.EncryptString(reflectorInfo);
            string tmp = tmpName + CommonOP.Spliter + tmpToolCode + CommonOP.Spliter + tmpDate + CommonOP.Spliter + tmpNum + CommonOP.Spliter + tmpReflectorInfo;
            tmp = AddCRC(tmp, false);
            tmp = AddCRC(tmp, true);
            tmp = AddCRC(tmp, false);
            tmp = AddCRC(tmp, true);
            return CommonOP.EncryptString(tmp);
        }
        /// <summary>
        /// 获取注册码
        /// </summary>
        /// <param name="account"></param>
        /// <returns></returns>
        public static string GetRegisterCode(Account account)
        {
            return GetRegisterCode(account.Name, account.Tool.Code, account.ExpireDate, account.Number, account.Tool.SpecialInfo);
        }

        /// <summary>
        /// 添加CRC验证码
        /// </summary>
        /// <param name="origin"></param>
        /// <param name="head"></param>
        /// <returns></returns>
        protected static string AddCRC(string origin,bool head)
        {
            int tmp = 0;
            for (int i = 0; i < origin.Length; i++)
            {
                tmp += char.ConvertToUtf32(origin, i);
            }
            if (head)
            {
                return char.ConvertFromUtf32(tmp % 26 + 65) + origin;
            }
            else
            {
                return origin + char.ConvertFromUtf32(tmp % 26 + 65);
            }
        }


        /// <summary>
        /// 根据客户端提交的帐户信息，解析成帐户类
        /// </summary>
        /// <param name="clientInfo">客户端提交的帐户信息</param>
        /// <returns>帐户类</returns>
        protected static Account GetAccount(string clientInfo)
        {
            string[] infos = Base64.Decrypt(clientInfo).Split(SFL.CommonOP.Spliter.ToCharArray());
            if (infos.Length != 7 || infos[0] != "")
            {
                throw new BOL.BaseCustomException("fail");
            }
            BRL.Account act = new BYFW.Model.Register.BRL.Account();
            act.Name = infos[1].Trim();
            BRL.Tool tl = new BYFW.Model.Register.BRL.Tool();
            tl.GetProperties(infos[2].Trim());
            act.ToolID = tl.ID;
            act.SpecialInfo = infos[3].Trim();
            act.MachineCode = infos[4].Trim();
            act.RegisterCode = infos[5].Trim();
            act.Version = infos[6].Trim();
            if (tl.ID == 0 || act.Name == "" || act.MachineCode == "")
            {
                throw new BOL.BaseCustomException("fail");
            }
            return act;
        }

        /// <summary>
        /// 申请试用版，当帐户不存在时有效
        /// </summary>
        /// <param name="clientInfo">客户端提交的帐户信息</param>
        /// <returns>注册码或错误信息</returns>
        public static string TrivialAccount(string clientInfo)
        {
            try
            {
                Account act = GetAccount(clientInfo);
                if (act.ExistSpecialAccount())
                {
                    act.GetProperties(act.Name, act.ToolID, act.SpecialInfo);
                }
                else
                {
                    act.ExpireDate = DateTime.Now.AddDays(act.Tool.TryDays);
                    act.RegisterCode = GetRegisterCode(act);
                    act.Add();
                }
                return CommonOP.EncryptString(SFL.CommonOP.Spliter + Base64.Encrypt(act.RegisterCode));
            }
            catch (BOL.BaseCustomException ex)
            {
                return CommonOP.EncryptString(ex.Message);
            }
            catch
            {
                return CommonOP.EncryptString("serverFail");
            }

        }

        /// <summary>
        /// 验证帐户信息是否有效
        /// </summary>
        /// <param name="clientInfo">客户端提交的帐户信息</param>
        /// <param name="enableMachine">当前机器码不是本机时，是否激活本机，使其他机器实效</param>
        /// <returns>软件运行所需信息或错误信息</returns>
        public static string ValidateAccount(string clientInfo, bool enableMachine)
        {
            try
            {
                BRL.Account act = GetAccount(clientInfo);
                string mc = act.MachineCode;
                string rc = act.RegisterCode;
                if (act.ExistSpecialAccount())
                {
                    act.GetProperties(act.Name, act.ToolID, act.SpecialInfo);
                    if (act.MachineCode == "" && mc != "")
                    {
                        act.MachineCode = mc;
                        act.Update();
                    }
                }
                else
                {
                    return CommonOP.EncryptString("fail");
                }
                if (act.ExpireDate < DateTime.Now)
                {
                    return CommonOP.EncryptString("expire");
                }
                if (act.RegisterCode != rc)
                {
                    return CommonOP.EncryptString("fail");
                }
                if (!act.IsEnterprise && act.MachineCode != mc)
                {
                    if (enableMachine && act.Tool.ChangeMC)
                    {
                        act.MachineCode = mc;
                        act.Update();
                    }
                    else
                    {
                        return CommonOP.EncryptString("occupy");
                    }
                }
                if (act.IsEnterprise)
                {
                    if (act.MCRanger.IndexOf(mc + ";") == -1)
                    {
                        return CommonOP.EncryptString("fail");
                    }
                }
                return CommonOP.EncryptString(SFL.CommonOP.Spliter + Base64.Encrypt(act.Name + SFL.CommonOP.Spliter + act.RegisterCode + SFL.CommonOP.Spliter + act.Tool.SpecialInfo));
            }
            catch (BOL.BaseCustomException ex)
            {
                return CommonOP.EncryptString(ex.Message);
            }
            catch
            {
                return CommonOP.EncryptString("serverFail");
            }
        }

        /// <summary>
        /// 获取新版本
        /// </summary>
        /// <param name="clientInfo">客户端提交的帐户信息</param>
        /// <returns>新版本链接或错误信息</returns>
        public static string GetNewVersionUrl(string clientInfo)
        {
            try
            {
                BRL.Account act = GetAccount(clientInfo);
                string mc = act.MachineCode;
                string rc = act.RegisterCode;
                string version = act.Comment;
                if (act.ExistSpecialAccount())
                {
                    act.GetProperties(act.Name, act.ToolID, act.SpecialInfo);
                    if (act.MachineCode == "" && mc != "")
                    {
                        act.MachineCode = mc;
                        act.Update();
                    }
                }
                else
                {
                    return CommonOP.EncryptString("fail");
                }
                if (act.ExpireDate < DateTime.Now)
                {
                    return CommonOP.EncryptString("expire");
                }
                if (act.RegisterCode != rc)
                {
                    return CommonOP.EncryptString("fail");
                }
                if (version == act.Tool.LastVersion)
                {
                    return CommonOP.EncryptString("isLatest");
                }
                if (!act.Tool.ClientValidate)
                {
                    if (!act.IsEnterprise && act.MachineCode != mc)
                    {
                        return CommonOP.EncryptString("occupy");
                    }
                    if (act.IsEnterprise)
                    {
                        if (act.MCRanger.IndexOf(mc + ";") == -1)
                        {
                            return CommonOP.EncryptString("fail");
                        }
                    }
                }

                return CommonOP.EncryptString(SFL.CommonOP.Spliter + Base64.Encrypt(act.Tool.Url));
            }
            catch (BOL.BaseCustomException ex)
            {
                return CommonOP.EncryptString(ex.Message);
            }
            catch
            {
                return CommonOP.EncryptString("serverFail");
            }
        }

        private void Test()
        {
            string rc = GetRegisterCode("baoyang", "etool", DateTime.MaxValue, 100, "RegInfo");
            Console.WriteLine(rc);
            Console.WriteLine(rc.Length);
        }

#endif
    }
}
